package biz

import (
	"amount1/internal/http_resty"
	"context"
	"errors"
	"fmt"
	"github.com/gogf/gf/util/gconv"
	jsoniter "github.com/json-iterator/go"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/trace"
	"net/http"
	"time"
)

// POST 请求
// Notice time.Sleep 2秒 测试～
func (a *Amount1BizStruct) httpPostCtxWithoutCancel(ctx context.Context, name string) error {
	ctx, span := otel.Tracer("BIZ").Start(ctx, "httpPostCtxWithoutCancelBiz", trace.WithSpanKind(trace.SpanKindInternal))
	defer span.End()

	time.Sleep(time.Second * 2)

	meta := http_resty.HttpRequestMeta{
		Name: name,
	}

	// Notice 这里为了打印转的
	paramsStr, errParams := jsoniter.MarshalToString(meta)
	if errParams != nil {
		return errors.New(fmt.Sprintf("jsonMarshal失败! err: %v", errParams))
	}
	fmt.Println("POST发送的请求体为: ", paramsStr)

	result := make(map[string]any)
	// Notice 测试了下 有时候通过result拿不到结果，实际最好测试下，用resp去获取结果！
	resp, errResp := a.httpRestyClient.R().
		SetContext(ctx).
		EnableTrace().
		SetHeader("Content-Type", "application/json;charset=utf-8").
		SetBody(meta). // Notice 可以直接把结构体放到body中
		SetResult(&result).
		Post("http://127.0.0.1:9099/index")
	if errResp != nil {
		return errors.New(fmt.Sprintf("发送POST请求失败! err: %v", errResp))
	}

	// Notice 注意: errResp 不能cover住 404 这个错误!最好单独判断下返回的错误码!防止接口404后面处理异常了
	// statusCode
	if resp.StatusCode() != http.StatusOK {
		// trace
		span.SetAttributes(
			attribute.String("url", "http://127.0.0.1:9099/index"),
			attribute.String("httpResp", gconv.String(resp)),
			attribute.String("statusCode", gconv.String(resp.StatusCode())),
		)
		return errors.New(fmt.Sprintf("POST请求返回的错误码: %v, 请求的URL: %v", resp.StatusCode(), "http://127.0.0.1:9099/index"))
	}

	// Notice 设置trace
	span.SetAttributes(attribute.String("httpRequestTraceInfo", gconv.String(resp.Request.TraceInfo())), attribute.String("httpResponse", gconv.String(resp)))

	fmt.Println("result: ", result)

	return nil
}

// GET 请求
// Notice time.Sleep 2秒 测试～
func (a *Amount1BizStruct) httpGetCtxWithoutCancel(ctx context.Context, name string) error {
	ctx, span := otel.Tracer("BIZ").Start(ctx, "httpGetCtxWithoutCancelBiz", trace.WithSpanKind(trace.SpanKindInternal))
	defer span.End()

	time.Sleep(time.Second * 2)
	// Notice 测试了下 有时候通过result拿不到结果，实际最好测试下，用resp去获取结果！
	resp, errResp := a.httpRestyClient.R().
		// Notice GET请求这样发送参数
		SetQueryParams(map[string]string{
			"name": name,
		}).
		SetContext(ctx).
		EnableTrace().
		Get("http://127.0.0.1:9099/index")
	if errResp != nil {
		return errors.New(fmt.Sprintf("发送GET请求失败! err: %v", errResp))
	}

	// Notice 注意: errResp 不能cover住 404 这个错误!最好单独判断下返回的错误码!防止接口404后面处理异常了
	// statusCode
	if resp.StatusCode() != http.StatusOK {
		// trace
		span.SetAttributes(
			attribute.String("url", "http://127.0.0.1:9099/index"),
			attribute.String("httpResp", gconv.String(resp)),
			attribute.String("statusCode", gconv.String(resp.StatusCode())),
		)
		return errors.New(fmt.Sprintf("GET请求返回的错误码: %v, 请求的URL: %v", resp.StatusCode(), "http://127.0.0.1:9099/index"))
	}

	// Notice 设置trace
	span.SetAttributes(attribute.String("httpRequestTraceInfo", gconv.String(resp.Request.TraceInfo())), attribute.String("httpResponse", gconv.String(resp)))

	fmt.Printf("GET收到的响应为: %T, %v \n", resp, resp)

	return nil
}
